#include "ChatService.hpp"
#include "public.hpp"
#include <muduo/base/Logging.h>
// 把实例对象写为静态类型这样子还不会有线程安全的问题
ChatService *ChatService::instance()
{
    // 调用构造函数生成唯一实例
    static ChatService megType;
    // 返回static对象
    return &megType;
}

handler ChatService::getHandler(int messageid)
{
    auto it = _megHandlerMap.find(messageid);
    // 关于这个怎么处理的等下再看看
    if (it == _megHandlerMap.end())
    {
        // 下面是我的处理方法 ， 这种处理方法有点挫了
        //    LOG_ERROR << "The messageid is not find in MessageHandlerMap";
        //    return;
        // 使用lambda表达式处理
        return [=](const muduo::net::TcpConnectionPtr &conn, json &js, muduo::Timestamp time)
        {
            LOG_ERROR << "The messageid is : " << messageid << " not find in MessageHandlerMap";
        };
    }

    return _megHandlerMap[messageid];
}

ChatService::ChatService()
{
    //_MegHandlerMap.insert(std::make_pair(LOGIN_MSG, std::bind(&ChatService::Login, this, _1, _2, _3)));
    //_MegHandlerMap.insert(std::make_pair(REG_MSG, std::bind(&ChatService::Register, this, _1, _2, _3)));

    _megHandlerMap.insert({LOGIN_MSG, std::bind(&ChatService::Login, this, _1, _2, _3)});
    _megHandlerMap.insert({REG_MSG, std::bind(&ChatService::Register, this, _1, _2, _3)});
}

void ChatService::Login(const muduo::net::TcpConnectionPtr &conn, json &js, muduo::Timestamp time)
{
    // 使用id和password进行登录业务
    int id = js["id"].get<int>();
    std::string password = js["password"];

    // 从数据库中查找比对是否有对应的用户
    User user = _userModel.query(id);
    // Id 不等于-1说明 有这个id的用户，如果password也匹配上了那么就登录成功
    if (user.getId() != -1 && user.getPassword() == password)
    {
        // “挤号了”
        if (user.getState() == "online")
        {
            json js;
            js["error"] = 2;
            js["errorMeg"] = "该账号已经登录";
            js["return Type"] = LOGIN_MSG_ACK;
            conn->send(js.dump());
        }
        else if (user.getState() == "offline")
        {
            // 登录成功
            _userModel.updateState(user);

            json js;
            js["error"] = 0;
            js["return Type"] = LOGIN_MSG_ACK;
            js["LoginMeg"] = "您已经登陆成功";
            conn->send(js.dump());
        }
    }
    else
    {
        json js;
        js["error"] = 1;
        js["return Type"] = LOGIN_MSG_ACK;
        js["LoginMeg"] = "账号或密码错误";
        js["id"] = user.getId();
        js["name"] = user.getName();
        conn->send(js.dump());
    }
}

void ChatService::Register(const muduo::net::TcpConnectionPtr &conn, json &js, muduo::Timestamp time)
{
    // 约定 ：注册业务，对端必须发来对应的name和password,还有标识业务方法的messageid
    std::string name = js["name"];
    std::string password = js["password"];
    std::string state = "offline";

    User user;
    user.setName(name);
    user.setPassword(password);

    // 调用成功，返回这个用户的id，将返回标识设为1（因为返回的信息不一定执行成功了，所以一定要一个返回标识）
    json responce;
    if (_userModel.insert(user))
    {
        responce["id"] = user.getId();
        responce["error"] = 0;
        responce["return Type"] = REG_MSG_ACK;

        conn->send(responce.dump());
    }
    else
    {
        responce["error"] = 1;
        responce["errorMessaege"] = "The business of register failed";
        responce["return Type"] = REG_MSG_ACK;

        conn->send(responce.dump());
    }
}